using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using PloobsEngine.Cameras;
using PloobsEngine.Components;

namespace PloobsEngine.Features
{
    public class SkyDome : BasicComponent
    {       
        
        private Effect effect;        
        private ICamera cam;
        public static readonly String MyName = "SkyDome";
        Model skyDome;
        Texture2D cloudMap0;
        Texture2D cloudMap1;
        float speed = 1;
        float difSpeed = 10;
        private bool initialized = false;

        #region Initialize
        public SkyDome() 
        {           
            
        }

   
        public override void Initialize()
        {
            effect = EngineStuff.InternalContentManager.GetAsset<Effect>("ByPassEffect");
            skyDome = EngineStuff.InternalContentManager.GetAsset<Model>("dome");   
            initialized = true;
        }

        #endregion

        internal void setParameters(ICamera cam, String  tex)
        {
            this.cam = cam;
            this.cloudMap0 = EngineStuff.CustomContentManager.GetAsset<Texture2D>(tex);
            this.cloudMap1 = EngineStuff.CustomContentManager.GetAsset<Texture2D>(tex);
        }

        internal void setParameters(ICamera cam, String tex0, String tex1, float Speed, float difSpeed)
        {
            this.cam = cam;
            this.speed = Speed;
            this.difSpeed = difSpeed;
            this.cloudMap0 = EngineStuff.CustomContentManager.GetAsset<Texture2D>(tex0);
            this.cloudMap1 = EngineStuff.CustomContentManager.GetAsset<Texture2D>(tex1);
        }  
        
        #region Draw

       
        public void Draw(GameTime gameTime , Matrix activeView , Matrix ActiveProjection)
        {            
             if (!initialized || cam == null)
             {                
                return;
             }
             
             EngineStuff.GraphicsDevice.RenderState.DepthBufferWriteEnable = false;            
             EngineStuff.GraphicsDevice.RenderState.DepthBufferEnable = false;
             //EngineStuff.GraphicsDevice.RenderState.CullMode = CullMode.CullClockwiseFace;
     
             Matrix[] modelTransforms = new Matrix[skyDome.Bones.Count];
             skyDome.CopyAbsoluteBoneTransformsTo(modelTransforms);             
             Matrix x = Matrix.Invert(activeView);             
             Vector3 camPos = new Vector3(x.M41, x.M42, x.M43);
             Matrix wMatrix = Matrix.CreateTranslation(0, -0.4f, 0) * Matrix.CreateScale(20) * Matrix.CreateTranslation(camPos) ;
         
             foreach (ModelMesh mesh in skyDome.Meshes)
                {
                     Matrix worldMatrix = modelTransforms[mesh.ParentBone.Index] * wMatrix;
                     effect.Parameters["World"].SetValue(worldMatrix);
                     effect.Parameters["ViewProjection"].SetValue(activeView * ActiveProjection);
                     effect.Parameters["xTexture0"].SetValue(cloudMap0);
                     effect.Parameters["xTexture1"].SetValue(cloudMap1);
                     effect.Parameters["mTexOffset0"].SetValue(mTexOffset0);
                     effect.Parameters["mTexOffset1"].SetValue(mTexOffset1); 
                     EngineStuff.GraphicsDevice.Indices = mesh.IndexBuffer;                        

                     foreach (ModelMeshPart meshPart in mesh.MeshParts)
                     {
                         EngineStuff.GraphicsDevice.VertexDeclaration = meshPart.VertexDeclaration;
                         EngineStuff.GraphicsDevice.Vertices[0].SetSource(mesh.VertexBuffer, meshPart.StreamOffset, meshPart.VertexStride);                         
                         effect.Begin();
                         effect.CurrentTechnique.Passes[0].Begin();
                         EngineStuff.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, meshPart.BaseVertex, 0, meshPart.NumVertices, meshPart.StartIndex, meshPart.PrimitiveCount);
                         effect.CurrentTechnique.Passes[0].End();
                         effect.End();
                     }            
             
         }

             EngineStuff.GraphicsDevice.RenderState.DepthBufferWriteEnable = true;
             EngineStuff.GraphicsDevice.RenderState.DepthBufferEnable = true;
             //EngineStuff.GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace;
     }
        Vector2 mTexOffset0;
        Vector2 mTexOffset1;
        public override void Update(GameTime gt)
        {
            float dt = (float)gt.ElapsedGameTime.TotalMilliseconds;
            mTexOffset0 += new Vector2(0.11f, 0.05f) * dt / 500000 * speed * difSpeed;
            mTexOffset1 += new Vector2(0.25f, 0.1f) * dt / 500000 * speed;

            // Textures repeat every 1.0 unit, so reset back down to zero
            // so the coordinates do not grow.
            if (mTexOffset0.X >= 1.0f || mTexOffset0.X <= -1.0f)
                mTexOffset0.X = 0.0f;
            if (mTexOffset1.X >= 1.0f || mTexOffset1.X <= -1.0f)
                mTexOffset1.X = 0.0f;
            if (mTexOffset0.Y >= 1.0f || mTexOffset0.Y <= -1.0f)
                mTexOffset0.Y = 0.0f;
            if (mTexOffset1.Y >= 1.0f || mTexOffset1.Y <= -1.0f)
                mTexOffset1.Y = 0.0f;

        }

        #endregion
        
        #region IReciever Members

        public override string getMyName()
        {
            return MyName;
        }
                
        #endregion

        #region IComponent Members

        public override ComponentType ComponentType
        {
            get { return ComponentType.PRE_DRAWABLE_AND_UPDATEABLE; }
        }

        public override void PreDraw(GameTime gt, Matrix activeView, Matrix activeProjection)
        {
            Draw(gt,activeView,activeProjection);
        }

        #endregion
    }
}
